home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 May: Tool Chest / Developer CD Series Tool Chest (Apple Computer)(May 1999).iso / Tool Chest / Games / Game Sample Code / ZAM 1.0a13 / GameSource / ExplosionSprites.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-16  |  5.4 KB  |  202 lines  |  [TEXT/KAHL]

  1. /*
  2.     Explosion Sprites
  3.     this is the code for handling the animated explosions in ZAM.
  4.     
  5. */
  6. #include "ZAM.h"
  7. #include "SpriteFrameRates.h"
  8. #include "GameSounds.h"
  9. #include "ZAMProtos.h"
  10.  
  11. #define kFirstExpFrameNum    0
  12. #define kLastExpFrameNum    5
  13.  
  14. spritePtr GetExplosionSprite(gamePtr game);
  15.  
  16. /* these are the globals used by this file.  They are private to this file */
  17. /* other parts of the game deal with explosions by calling the routines in this file */
  18.  
  19. static spriteLayerPtr    gExplosionLayer;
  20. static spritePtr        gExplosionSprite[kMaxExp];
  21.  
  22. void StartExplosionHere(gamePtr game, Fixed h, Fixed v)
  23. /*
  24.     This is the main explosion generation routine.  When you want one,
  25.     just call this and pass the fixed point coordinates, and an explosion will
  26.     start.  The game parameter is not really used any more, but the explosion list
  27.     used to be kept in it. 
  28. */
  29. {
  30.     spritePtr    thisExp;
  31.  
  32.     thisExp = GetExplosionSprite(game);
  33.  
  34.     if(thisExp != nil) {
  35.         thisExp->visible = false;
  36.         SetSpriteCurrentFrame(thisExp,0);
  37.         SetSpriteLoc(thisExp, h, v);
  38.         thisExp->visible = true;
  39.         (void)PlaySndAsynchChannel( kExplode, kExplosionChan, kStdPriority);
  40.         StartSpriteAction(thisExp);
  41.     }    
  42. }
  43.  
  44.  
  45. spritePtr GetExplosionSprite(gamePtr game)
  46. /* 
  47.         this function returns a spritePtr that is to be used for a new
  48.         explosion.  At one time I had an elaborate queueing scheme the prevented searching a list,
  49.         but then I simplified it in order to reduce complexity and track down bugs in other parts of
  50.         the code.
  51.         
  52.  */
  53. {
  54.     short        i;
  55.     
  56.     for(i = 0; i < kMaxExp; i++) {
  57.         if(!gExplosionSprite[i]->inUse) {
  58.             gExplosionSprite[i]->inUse = true;
  59.             return gExplosionSprite[i];
  60.         }
  61.     }
  62.     
  63.     return nil;
  64. }
  65.  
  66. Boolean ExplosionLastFrameProc(spritePtr expSprite, frameCellPtr frame)
  67. /*
  68.     On the last frame of animation we want to hide the explosion
  69.     so it erases properly, so explosion sprites are created with a frame callback
  70.     on the last frame of animation.
  71. */
  72. {
  73.  
  74.     expSprite->visible = false;                            // hide it
  75.     expSprite->inUse = false;                            // free it up
  76.     StopSpriteAction(expSprite);                        // stop its clock
  77.     expSprite->spriteFlags |= kNeedsToBeErased;            // flag it for updating
  78.     expSprite->ownerLayer->layerFlags |= kLayerDirty;    // be sure the layer is flagged too
  79.     
  80.     return false;                                        // don't want to be re-inserted in timer
  81. }
  82.  
  83.  
  84. Boolean FirstFrameProc(spritePtr explosionSprite, frameCellPtr frame)
  85. /*
  86.     Make sure the sprite is visible on the first frame of animation.
  87.     I forget why I do this, I think it was because of problems when one explosion was
  88.     cancelled to start a new one.
  89. */
  90. {
  91.     explosionSprite->visible = true;                    // just make sure we are visible
  92.     return true;
  93. }
  94.  
  95.  
  96. void StartExplosionMoving(gamePtr game, Fixed h, Fixed v, fixPt *vel)
  97. /*
  98.     This routine was used when I wanted the explosions to drift around
  99.     but I don't use it anymore.  The explosions will move though if you
  100.     replace StartExplosionHere with this.  Pretty handy.
  101. */
  102.  
  103. {
  104.     spritePtr    thisExp;
  105.  
  106.     thisExp = GetExplosionSprite(game);
  107.  
  108.     if(thisExp == nil)     { /* no more free explosions */
  109.         ErrMsg("\pNo More Explosions are available");
  110.     } else {
  111.         thisExp->visible = false;
  112.         /* prevent any drawing */
  113.         StopSpriteAction(thisExp);
  114.         SetSpriteCurrentFrame(thisExp,0);
  115.         SetSpriteLoc(thisExp, h, v);
  116.         SetSpriteVelocity(thisExp, vel->h >> 1, vel->v >> 1);
  117.         thisExp->moveTimeInterval = 100;
  118.  
  119.         thisExp->visible = true;
  120.         StartSpriteAction(thisExp);
  121.     }
  122. }
  123.  
  124. void LoadExplosionSprites(gamePtr game)
  125. /*
  126.     This function loads all the graphics for the explosion sprites
  127.     and also creates all of them.  The game is limited to a fixed 
  128.     number of explosions happening at any one time.
  129. */
  130. {
  131.     OSErr            err;
  132.     short            ref;
  133.     frameSetPtr        expFrameSet;
  134.     short            i;
  135.     short            y;
  136.     
  137.     ref = OpenResFile("\pExplosionFrames.rsrc");
  138.             
  139.     err = CreateColorIconFrameSet(&expFrameSet, kBaseID, kMaxExpFrames);
  140.     if(err != noErr) {
  141.         ErrMsgCode("\pCreateColorIconFrameSet failed.",err);
  142.     }
  143.     if(err == noErr)
  144.         SetFrameSetCTSeed(expFrameSet,game->gameCTSeed);
  145.  
  146.  
  147.     err = CreateSpriteLayer(&gExplosionLayer,game->tween,game->backdrop,game->gameWind);
  148.     if(err != noErr) {
  149.         ErrMsgCode("\pCreateSpriteLayer failed.",err);
  150.     }
  151.         
  152.     if(err == noErr) {
  153.         err = CreateEmptySprite(gExplosionLayer,
  154.                             &gExplosionSprite[0],    /* returned sprite here */
  155.                             kDefaultFrameAdvance,
  156.                             0,                                     /* time between movement */
  157.                             kExplosionFrameTime,                 /* time between frame change */
  158.                             (long)game);                        /* refcon, ptr to game */
  159.  
  160.         if(err != noErr) {
  161.             ErrMsgCode("\pCreateEmptySprite failed.",err);
  162.         } else {
  163.             /* install the missile frame set */
  164.             gExplosionSprite[0]->frameList = expFrameSet;
  165.         }
  166.     }
  167.     
  168.     
  169.     for(i = 1; i < kMaxExp; i++) {
  170.         if(err == noErr) {
  171.             err = CreateEmptySprite(gExplosionLayer,
  172.                                 &gExplosionSprite[i],    /* returned sprite here */
  173.                                 kDefaultFrameAdvance,
  174.                                 0,                             /* time between movement */
  175.                                 kExplosionFrameTime,         /* time between frame change */
  176.                                 (long)game);
  177.     
  178.             if(err != noErr) {
  179.                 ErrMsgCode("\pCreateEmptySprite failed.",err);
  180.             }
  181.         }
  182.         
  183.         if(err == noErr) {
  184.             /* dup the frame set */
  185.             err = CopyFrameSet(expFrameSet, &gExplosionSprite[i]->frameList);
  186.             if(err != noErr) {
  187.                 ErrMsgCode("\pCopyFrameSet failed!",err);
  188.             }
  189.         }
  190.     }
  191.     
  192.     for(i = 0; i < kMaxExp; i++) {
  193.         SetSpriteFrameCallback(gExplosionSprite[i],kFirstExpFrameNum,FirstFrameProc);
  194.         SetSpriteFrameCallback(gExplosionSprite[i],kLastExpFrameNum,ExplosionLastFrameProc);
  195.         SetSpriteFrameRef(gExplosionSprite[i],kLastExpFrameNum, i);
  196.         gExplosionSprite[i]->inUse = false;
  197.     }
  198.  
  199.     CloseResFile(ref);
  200.  
  201. }
  202.